package com.derbysoft.lowcostadapter.commons.repository.impl;

import com.derbysoft.common.paginater.Paginater;
import com.derbysoft.lowcostadapter.commons.model.Reservation;
import com.derbysoft.lowcostadapter.commons.repository.ReservationRepository;
import com.derbysoft.lowcostadapter.web.action.admin.reservation.ReservationCondition;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Repository("reservationRepository")
public class ReservationRepositoryImpl extends CommonService<Reservation> implements ReservationRepository {
    @Override
    public Reservation findByErsp(String erspCode) {
        return load("ersp", erspCode);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void create(String passport, String ersp) {
        Reservation reservation = new Reservation();
        reservation.setHotelPassport(passport);
        reservation.setErsp(ersp);
        reservation.setCreateTime(new Date());
        save(reservation);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void cancel(String ersp, String cancellationReference) {
        Reservation reservation = findByErsp(ersp);
        reservation.setCancellationReference(cancellationReference);
        reservation.setCancelTime(new Date());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateBookingReference(String ersp, String bookingReference) {
        Reservation reservation = findByErsp(ersp);
        reservation.setBookingReference(bookingReference);
        super.commonRepository.save(reservation);
    }

    @Override
    public void findByCondition(ReservationCondition condition, Paginater paginater) {
        DetachedCriteria criteria = DetachedCriteria.forClass(Reservation.class).addOrder(Order.desc("createTime"));
        super.paginater(populateCriteria(criteria, condition), paginater);
    }

    private DetachedCriteria populateCriteria(DetachedCriteria criteria, ReservationCondition condition) {
        if (condition == null) {
            return criteria;
        }
        if (StringUtils.isNotBlank(condition.getHotelPassport())) {
            criteria.add(Restrictions.eq("hotelPassport", condition.getHotelPassport()));
        }
        if (StringUtils.isNotBlank(condition.getErsp())) {
            criteria.add(Restrictions.ilike("ersp", condition.getErsp(), MatchMode.ANYWHERE));
        }
        if (StringUtils.isNotBlank(condition.getConfirmNumber())) {
            criteria.add(Restrictions.ilike("bookingReference", condition.getConfirmNumber(), MatchMode.ANYWHERE));
        }

        if (StringUtils.isNotBlank(condition.getCancelNo())) {
            criteria.add(Restrictions.ilike("cancellationReference", condition.getCancelNo(), MatchMode.ANYWHERE));
        }
        return criteria;
    }
}
